﻿
using System;
using System.Text.RegularExpressions;
namespace sharpxbot.Plugins.BibleSearch.Data
{
    public class QueryParser
    {
        public const string StartPattern = "**"; // optimization

        private static Regex queryRegex = new Regex( 
            //@"^(\*\*)(\s*)(?<book_name>\d*\p{L}+)(\s*)(\.|:)?(\s*)(?<chapter_index>\d{1,3})(\s*)([:](\s*)(?<start_verse>\d{1,5}(\s*))((\s*)[-](\s*)(?<end_verse>\d{1,5}))?)?|(?<full_text_search>[^*]+)$",
            //@"^(\*\*)(\s*)(?<book_name>\d*\p{L}+)(\s*)(\.|:)?(\s*)(?<chapter_index>\d{1,3})(\s*)([:](\s*)(?<start_verse>\d{1,5}(\s*))((\s*)[-](\s*)(?<end_verse>\d{1,5}))?)?|(\*\*(?<full_text_search>[^*]+))|(\*\*\*(?<fuzzy_search>.*))$",
            @"^(\*\*)(\s*)(?<book_name>\d*\p{L}+)(\s*)(\.|:)?(\s*)(?<chapter_index>\d{1,3})(\s*)([:](\s*)(?<start_verse>\d{1,5}(\s*))((\s*)[-](\s*)(?<end_verse>\d{1,5}))?)?|^(\*{2}\s*(?<full_text_search>[^*].+))|(\*{3}(?<fuzzy_search>.*))$",
            //@"^(\*\*)(\s*)(?<book_name>\d*\p{L}+)(\s*)(\.|:)?(\s*)(?<chapter_index>\d{1,3})(\s*)([:](\s*)(?<start_verse>\d{1,5}(\s*))((\s*)[-](\s*)(?<end_verse>\d{1,5}))?)?|(\*\*[[^\*]\s*](?<full_text_search>.+))|(\*\*\*(?<fuzzy_search>.*))$",
            RegexOptions.Compiled | RegexOptions.IgnoreCase
            );

        public Query BuildQuery(string str)
        {
            Query result = null;

            try
            {
                if (!String.IsNullOrWhiteSpace(str) && str.StartsWith(StartPattern))
                {
                    Match m = queryRegex.Match(str);
                    if (m.Success)
                    {
                        result = new Query();
                        result.FullTextSearch = m.Groups["full_text_search"].Value;
                        result.BookName = m.Groups["book_name"].Value;

                        int ival = -1;
                        if (Int32.TryParse(m.Groups["chapter_index"].Value, out ival))
                        {
                            result.ChapterIndex = ival;
                        }

                        if (Int32.TryParse(m.Groups["start_verse"].Value, out ival))
                        {
                            result.StartVerse = ival;
                        }

                        if (Int32.TryParse(m.Groups["end_verse"].Value, out ival))
                        {
                            result.EndVerse = ival;
                        }

                        result.FuzzySearch = m.Groups["fuzzy_search"].Value;
                    }
                }
            }
            catch { }

            return result;
        }
    }
}
